package com.ruoyi.huanjing.controller;

import com.ruoyi.common.annotation.Anonymous;
import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.common.utils.DictUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import ucar.nc2.*;
import ucar.nc2.Structure;

import java.io.IOException;
import java.util.*;
import java.util.stream.Collectors;

@RestController
public class TreeShuXing {

    @Autowired
    private RedisCache redisCache;

    // 假设的字典类型，可根据实际情况修改
    private static final String DICT_TYPE = "hj_bl";

    @Anonymous
    @GetMapping("/buildtree")
    public List<Map<String, Object>> buildtree(@RequestParam("filePath") String filePath) {
        List<Map<String, Object>> result = new ArrayList<>();
        int[] idCounter = {1}; // 使用数组实现可修改的计数器

        //动态获取盘符,进行替换
        String disk = redisCache.getCacheObject("disk").toString();
        filePath=disk+filePath.substring(2);

        try (NetcdfFile ncFile = NetcdfFile.open(filePath)) {
            // 获取根组
            Group rootGroup = ncFile.getRootGroup();

            // 查找所有组下的Data_Fields组
            List<Group> dataFieldsGroups = new ArrayList<>();
            findDataFieldsGroups(rootGroup, dataFieldsGroups);

            // 处理所有找到的Data_Fields组
            for (Group dataFieldsGroup : dataFieldsGroups) {
                // 添加Data_Fields组的子组（如果有）
                for (Group childGroup : dataFieldsGroup.getGroups()) {
                    result.add(buildGroupNode(childGroup, idCounter));
                }

                // 添加Data_Fields组的变量（只添加Geo2D类型）
                for (Variable var : dataFieldsGroup.getVariables()) {
                    // 跳过结构体成员变量
                    if (var.getParentStructure() == null) {
                        String varType = determineVariableType(var);
                        if (varType.equals("Geo2D")) {
                            result.add(buildVariableNode(var, idCounter));
                        }
                    }
                }
            }

        } catch (IOException e) {
            System.err.println("读取变量列表时出错: " + e.getMessage());
            e.printStackTrace();
            // 出错时返回空列表
        }
        return result;
    }

    // 构建组节点
    private Map<String, Object> buildGroupNode(Group group, int[] idCounter) {
        Map<String, Object> node = new LinkedHashMap<>();
        String name = group.getShortName();
        node.put("id", String.valueOf(idCounter[0]++));
        node.put("name", name);
        // 在构建节点时就进行字典替换
        node.put("label", getDictReplacedLabel(name));
        node.put("type", "group");
        node.put("fullName", group.getFullName());

        // 添加子节点
        List<Map<String, Object>> children = new ArrayList<>();

        // 先添加子组
        for (Group childGroup : group.getGroups()) {
            children.add(buildGroupNode(childGroup, idCounter));
        }

        // 再添加变量（只添加Geo2D类型）
        for (Variable var : group.getVariables()) {
            // 跳过结构体成员变量，它们会作为结构体的子节点
            if (var.getParentStructure() == null) {
                String varType = determineVariableType(var);
                if (varType.equals("Geo2D")) {
                    children.add(buildVariableNode(var, idCounter));
                }
            }
        }

        node.put("children", children);
        return node;
    }

    // 构建变量节点
    private Map<String, Object> buildVariableNode(Variable var, int[] idCounter) {
        Map<String, Object> node = new LinkedHashMap<>();
        String name = var.getShortName();
        node.put("id", String.valueOf(idCounter[0]++));
        node.put("name", name);
        // 在构建节点时就进行字典替换
        node.put("label", getDictReplacedLabel(name));
        node.put("fullName", var.getFullName());

        // 处理变量类型
        String varType = determineVariableType(var);
        node.put("type", varType);

        // 处理维度信息
        List<Dimension> dimensions = getEffectiveDimensions(var);
        if (!dimensions.isEmpty()) {
            node.put("dimensions", dimensions.stream()
                    .map(Dimension::getShortName)
                    .collect(Collectors.joining(", ")));
        }

        // 如果是结构体，添加成员变量作为子节点（只添加Geo2D类型）
        List<Map<String, Object>> members = new ArrayList<>();
        if (var instanceof Structure) {
            Structure struct = (Structure) var;
            for (Variable member : struct.getVariables()) {
                String memberType = determineVariableType(member);
                if (memberType.equals("Geo2D")) {
                    members.add(buildVariableNode(member, idCounter));
                }
            }
        }
        node.put("children", members);
        return node;
    }

    // 封装字典替换逻辑
    private String getDictReplacedLabel(String name) {
        String dictValue = DictUtils.getDictLabel(DICT_TYPE, name);
        return dictValue != null && !dictValue.isEmpty() ? dictValue : name;
    }

    // 确定变量类型
    private String determineVariableType(Variable var) {
        List<Dimension> dimensions = getEffectiveDimensions(var);
        int dimCount = dimensions.size();

        if (dimCount == 0 || dimensions.stream().anyMatch(d -> d.getLength() == 1)) {
            return "-";
        }

        // 仅当变量同时包含特定维度时才判定为 Geo2D 类型
        boolean has2NScans = dimensions.stream().anyMatch(d ->
                d.getShortName() != null && (d.getShortName().equals("2*nscans") || d.getShortName().equals("lat")) || d.getShortName().equals("YDim") || d.getShortName().equals("nscans*10"));


        boolean has1KMGeoDim = dimensions.stream().anyMatch(d ->
                d.getShortName() != null && (d.getShortName().equals("1KM_geo_dim") || d.getShortName().equals("lon")) || d.getShortName().equals("XDim")|| d.getShortName().equals("mframes"));



        if (has2NScans && has1KMGeoDim) {
            return "Geo2D";
        } else if (dimCount >= 2) {
            return "2D";
        } else {
            return dimCount + "D";
        }
    }

    // 获取有效维度
    private List<Dimension> getEffectiveDimensions(Variable var) {
        if (var.getDataType().isString() || var instanceof Structure) {
            return new ArrayList<>();
        }
        return var.getDimensions();
    }

    // 递归查找所有组下的Data_Fields组
    private void findDataFieldsGroups(Group group, List<Group> dataFieldsGroups) {
        // 检查当前组是否有Data_Fields子组
        for (Group childGroup : group.getGroups()) {
            if ("Data_Fields".equals(childGroup.getShortName())) {
                dataFieldsGroups.add(childGroup);
            }
            // 递归检查子组
            findDataFieldsGroups(childGroup, dataFieldsGroups);
        }
    }
}